import json
import os
import logging
import time
from pathlib import Path
from typing import Dict

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

# 保存文件版本
SAVE_VERSION = 1

# 获取保存文件绝对路径
SAVE_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'save.json')

# 备份配置
MAX_BACKUPS = 5  # 最大备份数量
BACKUP_DIR = os.path.join(os.path.dirname(SAVE_FILE), 'backups')
Path(BACKUP_DIR).mkdir(parents=True, exist_ok=True)

def _create_backup() -> bool:
    """创建备份文件"""
    if not os.path.exists(SAVE_FILE):
        return False
        
    try:
        timestamp = int(time.time())
        backup_file = os.path.join(BACKUP_DIR, f'save_{timestamp}.json')
        with open(SAVE_FILE, 'r') as src, open(backup_file, 'w') as dst:
            dst.write(src.read())
        logging.info(f"创建备份文件: {backup_file}")
        return True
    except Exception as e:
        logging.error(f"创建备份失败: {str(e)}")
        return False

def _cleanup_backups():
    """清理旧备份文件"""
    try:
        backups = sorted(Path(BACKUP_DIR).glob('save_*.json'))
        while len(backups) > MAX_BACKUPS:
            oldest = backups.pop(0)
            oldest.unlink()
            logging.info(f"删除旧备份: {oldest}")
    except Exception as e:
        logging.error(f"清理备份失败: {str(e)}")

def save_progress(save_data: Dict) -> bool:
    """保存游戏进度"""
    try:
        # 创建备份
        if os.path.exists(SAVE_FILE):
            _create_backup()
            _cleanup_backups()
            
        # 先写入临时文件，确保原子性
        temp_file = SAVE_FILE + '.tmp'
        with open(temp_file, 'w') as f:
            json.dump(save_data, f, indent=2)
            
        # 重命名临时文件为正式文件
        os.replace(temp_file, SAVE_FILE)
        logging.info(f"成功保存进度到 {SAVE_FILE}")
        return True
    except PermissionError:
        logging.error(f"没有权限写入文件: {SAVE_FILE}")
        return False
    except Exception as e:
        logging.error(f"保存进度失败: {str(e)}")
        return False

def _validate_save_data(data: Dict) -> bool:
    """验证保存数据是否有效"""
    try:
        if not isinstance(data, dict):
            return False
            
        if data.get('version') != SAVE_VERSION:
            return False
            
        if not isinstance(data.get('current_level'), int):
            return False
            
        if not isinstance(data.get('levels'), dict):
            return False
            
        # 验证关卡数量是否匹配
        from levels import LEVELS
        levels_data = data['levels']
        if len(levels_data) != len(LEVELS):
            return False
            
        # 验证关卡数据格式
        for level_data in levels_data.values():
            if not isinstance(level_data, dict):
                return False
            # 兼容旧版本保存文件，缺少move_count时自动添加
            if not all(key in level_data for key in ['completed', 'time']):
                return False
            if 'move_count' not in level_data:
                level_data['move_count'] = 0
                
        return True
    except:
        return False

def _try_load_backup() -> Dict:
    """尝试从备份文件加载进度"""
    from levels import LEVELS
    
    # 初始化默认保存数据
    default_save_data = {
        'version': SAVE_VERSION,
        'current_level': 1,
        'levels': {
            i+1: {'completed': False, 'time': 0, 'move_count': 0}
            for i in range(len(LEVELS))
        }
    }
    
    try:
        backups = sorted(Path(BACKUP_DIR).glob('save_*.json'), reverse=True)
        # 限制最大尝试次数
        max_attempts = min(len(backups), MAX_BACKUPS)
        for backup in backups[:max_attempts]:
            try:
                with open(backup, 'r') as f:
                    data = json.load(f)
                    if _validate_save_data(data):
                        # 合并保存的数据和默认数据结构
                        merged_data = default_save_data.copy()
                        merged_data.update(data)
                        
                        # 确保所有关卡都有move_count字段
                        for level_id in merged_data['levels']:
                            if 'move_count' not in merged_data['levels'][level_id]:
                                merged_data['levels'][level_id]['move_count'] = 0
                                
                        logging.warning(f"从备份文件 {backup} 恢复进度")
                        return merged_data
            except:
                continue
                
        logging.error("所有备份文件均无效")
        return default_save_data
    except Exception as e:
        logging.error(f"加载备份失败: {str(e)}")
        return default_save_data

def _repair_save_file() -> bool:
    """尝试修复损坏的保存文件"""
    try:
        if not os.path.exists(SAVE_FILE):
            return False
            
        # 读取原始文件内容
        with open(SAVE_FILE, 'r') as f:
            content = f.read()
            
        # 尝试解析JSON
        try:
            data = json.loads(content)
            if _validate_save_data(data):
                return True  # 文件正常
        except json.JSONDecodeError:
            pass
            
        # 尝试修复JSON格式
        try:
            # 删除注释
            content = '\n'.join(line for line in content.splitlines() 
                              if not line.strip().startswith('//'))
                              
            # 尝试解析
            data = json.loads(content)
            if _validate_save_data(data):
                # 保存修复后的文件
                with open(SAVE_FILE, 'w') as f:
                    json.dump(data, f, indent=2)
                logging.info("成功修复保存文件")
                return True
        except:
            pass
            
        # 如果修复失败，删除损坏的文件
        os.remove(SAVE_FILE)
        logging.warning("无法修复保存文件，已删除")
        return False
    except Exception as e:
        logging.error(f"修复保存文件失败: {str(e)}")
        return False

def load_progress() -> Dict:
    """加载游戏进度"""
    from levels import LEVELS
    
    # 初始化默认保存数据
    default_save_data = {
        'version': SAVE_VERSION,
        'current_level': 1,
        'levels': {
            i+1: {'completed': False, 'time': 0, 'move_count': 0}
            for i in range(len(LEVELS))
        }
    }
    
    if not os.path.exists(SAVE_FILE):
        logging.info("未找到保存文件，使用默认进度")
        return default_save_data
        
    try:
        with open(SAVE_FILE, 'r') as f:
            data = json.load(f)
            
            # 检查保存文件版本
            if not _validate_save_data(data):
                logging.warning("保存文件数据无效，尝试从备份恢复")
                return _try_load_backup()
                
            # 合并保存的数据和默认数据结构
            merged_data = default_save_data.copy()
            merged_data.update(data)
            
            # 确保所有关卡都有move_count字段
            for level_id in merged_data['levels']:
                if 'move_count' not in merged_data['levels'][level_id]:
                    merged_data['levels'][level_id]['move_count'] = 0
                    
            logging.info("成功加载游戏进度")
            return merged_data
    except json.JSONDecodeError:
        logging.error("保存文件格式错误，尝试从备份恢复")
        return _try_load_backup()
    except PermissionError:
        logging.error(f"没有权限读取文件: {SAVE_FILE}")
        return default_save_data
    except Exception as e:
        logging.error(f"加载进度失败: {str(e)}，尝试从备份恢复")
        return _try_load_backup()
